/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.fabianterhorst.isometric.slice;

import io.fabianterhorst.isometric.Color;
import io.fabianterhorst.isometric.Constant;
import io.fabianterhorst.isometric.HiLogs;
import io.fabianterhorst.isometric.Isometric;
import io.fabianterhorst.isometric.IsometricView;
import io.fabianterhorst.isometric.Path;
import io.fabianterhorst.isometric.Point;
import io.fabianterhorst.isometric.ResourceTable;
import io.fabianterhorst.isometric.shapes.Cylinder;
import io.fabianterhorst.isometric.shapes.Knot;
import io.fabianterhorst.isometric.Shape;
import io.fabianterhorst.isometric.shapes.Octahedron;
import io.fabianterhorst.isometric.shapes.Prism;
import io.fabianterhorst.isometric.shapes.Pyramid;
import io.fabianterhorst.isometric.shapes.Stairs;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.Text;

/**
 * MainAbilitySlice.
 *
 * @since 2021-03-11
 */
public class MainAbilitySlice extends AbilitySlice {
    /**
     * To get class name
     */
    private static final String TAG = MainAbilitySlice.class.getName();

    IsometricView isometricView;

    ComponentContainer container;

    Text text;

    private String item;

    /**
     * callback
     *
     * @param intent
     */
    @Override
    public void onStart(Intent intent) {

        super.onStart(intent);

        container = (ComponentContainer) LayoutScatter.getInstance(this)
            .parse(ResourceTable.Layout_ability_main, null, false);
        isometricView = (IsometricView) container.findComponentById(ResourceTable.Id_isometricView);
        text = (Text) container.findComponentById(ResourceTable.Id_isometricShapeDescription);
        isometricView.setClickListener(new IsometricView.OnItemClickListener() {
            @Override
            public void onClick(Isometric.Item item) {

            }
        });
        item = intent.getStringParam(ListAbilitySlice.LIST_ITEM);
        HiLogs.e(TAG, " item" + item);
        switch (item) {

            case Constant.MULTIPLE_SHAPES:
                text.setText(Constant.MULTIPLE_SHAPE_DESC);
                multipleShapes(isometricView);
                break;
            case Constant.COMPLEX_SHAPE_1:
                text.setText(Constant.COMPLEX_SHAPE_1_DESC);
                complexShapeOne(isometricView);
                break;
            case Constant.COMPLEX_SHAPE_2:
                text.setText(Constant.COMPLEX_SHAPE_2_DESC);
                complexShapeTwo(180, isometricView);
                break;
            case Constant.DRAW_COMPLEX_PRISM:
                text.setText(Constant.DRAW_COMPLEX_PRISM_DESC);
                drawComplextPrism(isometricView);
                break;
            case Constant.DRAW_PRISM_1:
                text.setText(Constant.DRAW_PRISM_1_DESC);
                drawPrismOne(isometricView);
                break;
            case Constant.DRAW_PRISM_2:
                text.setText(Constant.DRAW_PRISM_2_DESC);
                drawPrismTwo(isometricView);
                break;
            case Constant.DRAW_PRISM_3:
                text.setText(Constant.DRAW_PRISM_3_DESC);
                drawPrismThree(isometricView);
                break;
            case Constant.DRAW_PRISM_4:
                text.setText(Constant.DRAW_PRISM_4_DESC);
                drawPrismFour(isometricView);
                break;
            case Constant.DRAW_KNOT_1:
                text.setText(Constant.DRAW_KNOT_1_DESC);
                drawKnotOne(isometricView);
                break;
            case Constant.DRAW_KNOT_2:
                text.setText(Constant.DRAW_KNOT_2_DESC);
                drawKnotTwo(isometricView);
                break;
            case Constant.DRAW_KNOT_3:
                text.setText(Constant.DRAW_KNOT_3_DESC);
                drawKnotThree(isometricView);
                break;
            case Constant.DRAW_CYLINDER_1:
                text.setText(Constant.DRAW_CYLINDER_1_DESC);
                drawCylinderOne(isometricView);
                break;
            case Constant.DRAW_CYLINDER_2:
                text.setText(Constant.DRAW_CYLINDER_2_DESC);
                drawCylinderTwo(isometricView);
                break;
            case Constant.DRAW_CYLINDER_3:
                text.setText(Constant.DRAW_CYLINDER_3_DESC);
                drawCylinderThree(isometricView);
                break;
            case Constant.DRAW_CYLINDER_4:
                text.setText(Constant.DRAW_CYLINDER_4_DESC);
                drawCylinderFour(isometricView);
                break;
            case Constant.DRAW_OCTAHEDRON_1:
                text.setText(Constant.DRAW_OCTAHEDRON_1_DESC);
                drawOctahedronOne(180, isometricView);
                break;
            case Constant.DRAW_OCTAHEDRON_2:
                text.setText(Constant.DRAW_OCTAHEDRON_2_DESC);
                drawOctahedronTwo(180, isometricView);
                break;
            case Constant.DRAW_OCTAHEDRON_3:
                text.setText(Constant.DRAW_OCTAHEDRON_3_DESC);
                drawOctahedronThree(180, isometricView);
                break;
            case Constant.DRAW_PYRAMID_1:
                text.setText(Constant.DRAW_PYRAMID_1_DESC);
                drawPyramidOne(isometricView);
                break;
            case Constant.DRAW_PYRAMID_2:
                text.setText(Constant.DRAW_PYRAMID_2_DESC);
                drawPyramidTwo(isometricView);
                break;
            case Constant.DRAW_PYRAMID_3:
                text.setText(Constant.DRAW_PYRAMID_3_DESC);
                drawPyramidThree(isometricView);
                break;
            case Constant.DRAW_PYRAMID_4:
                text.setText(Constant.DRAW_PYRAMID_4_DESC);
                drawPyramidFour(isometricView);
                break;
            case Constant.DRAW_PYRAMID_5:
                text.setText(Constant.DRAW_PYRAMID_5_DESC);
                drawPyramidFive(isometricView);
                break;
            case Constant.DRAW_STAIRS_1:
                text.setText(Constant.DRAW_STAIRS_1_DESC);
                drawStairsOne(isometricView);
                break;
            case Constant.DRAW_STAIRS_2:
                text.setText(Constant.DRAW_STAIRS_2_DESC);
                drawStairsTwo(isometricView);
                break;
            case Constant.DRAW_STAIRS_3:
                text.setText(Constant.DRAW_STAIRS_3_DESC);
                drawStairsThree(isometricView);
                break;
        }

        super.setUIContent(container);
    }

    /**
     * grid
     *
     * @param isometricView
     */
    public void grid(IsometricView isometricView) {

        for (int x = 0; x < 10; x++) {
            isometricView.add(new Path(new Point[] {
                new Point(x, 0, 0), new Point(x, 10, 0), new Point(x, 0, 0)
            }), new Color(50, 160, 60));
        }
        for (int y = 0; y < 10; y++) {
            isometricView.add(new Path(new Point[] {
                new Point(0, y, 0), new Point(10, y, 0), new Point(0, y, 0)
            }), new Color(50, 160, 60));
        }
        isometricView.add(new Prism(Point.ORIGIN), new Color(33, 150, 243));
        isometricView.add(new Path(new Point[] {
            Point.ORIGIN, new Point(0, 0, 10), Point.ORIGIN
        }), new Color(160, 50, 60));
    }

    /**
     * path
     *
     * @param isometricView
     */
    public void path(IsometricView isometricView) {
        isometricView.add(new Prism(Point.ORIGIN, 3, 3, 1), new Color(50, 60, 160));
        isometricView.add(new Path(new Point[] {
            new Point(1, 1, 1), new Point(2, 1, 1), new Point(2, 2, 1), new Point(1, 2, 1)
        }), new Color(50, 160, 60));
    }

    /**
     * Draw complex Prism with grid and different color
     *
     * @param isometricView {@link IsometricView}
     */
    public void drawComplextPrism(IsometricView isometricView) {
        grid(isometricView);
        isometricView.add(new Prism(new Point(0, 0, 0), 1, 1, 0.2), new Color(50, 50, 50));
        isometricView.add(new Prism(new Point(1, 1, 1), 1, 1, 0.2), new Color(160, 60, 50));
        isometricView.add(new Prism(new Point(2, 2, 2), 1, 1, 0.2), new Color(160, 60, 50));
        isometricView.add(new Prism(new Point(3, 3, 3), 1, 1, 0.2), new Color(160, 60, 50));
        isometricView.add(new Prism(new Point(4, 4, 4), 1, 1, 0.2), new Color(33, 150, 243));
    }

    /**
     * Draw Prism with one translation point small
     *
     * @param isometricView {@link IsometricView}
     */
    public void drawPrismOne(IsometricView isometricView) {
        isometricView.add(new Prism(new Point(0, 0, 0), 1, 1, 0.2), new Color(50, 50, 50));
    }

    /**
     * Draw Prism with all negative coordinates
     *
     * @param isometricView {@link IsometricView}
     */
    public void drawPrismTwo(IsometricView isometricView) {
        isometricView.add(new Prism(new Point(-1, -1, -1)), new Color(33, 150, 243));
    }

    /**
     * Draw Prism with one negative coordinates and translation point very small
     *
     * @param isometricView {@link IsometricView}
     */
    public void drawPrismThree(IsometricView isometricView) {
        isometricView.add(new Prism(new Point(-1, 0, 0), 0.6, 0.6, 0.6), new Color(180, 0, 180));
    }

    /**
     * Draw Prism with translation point very big
     *
     * @param isometricView {@link IsometricView}
     */
    public void drawPrismFour(IsometricView isometricView) {
        isometricView.add(new Prism(new Point(0, 0, 0), 4, 4, 4), new Color(33, 150, 243));
    }

    /**
     * Draw Knot
     *
     * @param isometricView {@link IsometricView}
     */
    public void drawKnotOne(IsometricView isometricView) {
        isometricView.add(new Knot(new Point(2, 2, 2)), new Color(180, 180, 0));
    }

    /**
     * Draw Knot with all negative coordinates
     *
     * @param isometricView {@link IsometricView}
     */
    public void drawKnotTwo(IsometricView isometricView) {
        isometricView.add(new Knot(new Point(-1, -1, -1)), new Color(80, 0, 180));
    }

    /**
     * Draw Knot with one negative coordinates
     *
     * @param isometricView {@link IsometricView}
     */
    public void drawKnotThree(IsometricView isometricView) {
        isometricView.add(new Knot(new Point(-1, 0, 0)), new Color(33, 150, 243));
    }

    /**
     * Draw Cylinder
     *
     * @param isometricView {@link IsometricView}
     */
    public void drawCylinderOne(IsometricView isometricView) {
        HiLogs.e(TAG, " drawCylinderOne :  " + isometricView);
        isometricView.add(new Cylinder(new Point(3, 2, 3.2), 20, 8), new Color(180, 0, 180));
    }

    /**
     * Draw Cylinder with one negative coordinates and small height
     *
     * @param isometricView {@link IsometricView}
     */
    public void drawCylinderTwo(IsometricView isometricView) {
        HiLogs.e(TAG, "drawCylinderTwo :  " + isometricView);
        isometricView.add(new Cylinder(new Point(-1, 0, 0), 20, 2), new Color(50, 50, 50));
    }

    /**
     * Draw Cylinder with all negative coordinates with big height and different color
     *
     * @param isometricView {@link IsometricView}
     */
    public void drawCylinderThree(IsometricView isometricView) {
        HiLogs.e(TAG, " drawCylinderThree :  " + isometricView);
        isometricView.add(new Cylinder(new Point(-0.2, -0.2, -0.2), 30, 9), new Color(180, 0, 180));
    }

    /**
     * Draw Cylinder with two negative coordinates and big radius with very less height
     *
     * @param isometricView {@link IsometricView}
     */
    public void drawCylinderFour(IsometricView isometricView) {
        HiLogs.e(TAG, " drawCylinderFour :  " + isometricView);
        isometricView.add(new Cylinder(new Point(-1, -1, 1), 3, 20, 0.2), new Color(50, 50, 50));
    }

    /**
     * Draw Octahedron with rotation
     *
     * @param angle {@link double}
     * @param isometricView {@link IsometricView}
     */
    public void drawOctahedronOne(double angle, IsometricView isometricView) {
        isometricView.add(new Octahedron(new Point(3, 2, 3.2)).rotateZ(new Point(3.5, 2.5, 0), angle),
            new Color(0, 180, 180));
    }

    /**
     * Draw Octahedron with all negative coordinates
     *
     * @param angle {@link double}
     * @param isometricView {@link IsometricView}
     */
    public void drawOctahedronTwo(double angle, IsometricView isometricView) {
        isometricView.add(new Octahedron(new Point(-3, -2, -3.2)).rotateZ(new Point(3.5, 2.5, 0), angle),
            new Color(180, 0, 180));
    }

    /**
     * Draw Octahedron with one negative coordinates
     *
     * @param angle {@link double}
     * @param isometricView {@link IsometricView}
     */
    public void drawOctahedronThree(double angle, IsometricView isometricView) {
        isometricView.add(new Octahedron(new Point(-3, 2, 3.2)).rotateZ(new Point(3.5, 2.5, 0), angle),
            new Color(33, 150, 243));
    }

    /**
     * Draw Pyramid with scaling
     *
     * @param isometricView {@link IsometricView}
     */
    public void drawPyramidOne(IsometricView isometricView) {
        isometricView.add(new Pyramid(new Point(2, 3, 3)).scale(new Point(2, 4, 3), 0.5), new Color(180, 180, 0));
    }

    /**
     * Draw Pyramid with small translation point and zero coordinate
     *
     * @param isometricView {@link IsometricView}
     */
    public void drawPyramidTwo(IsometricView isometricView) {
        isometricView.add(new Pyramid(new Point(0, 0, 0), 1, 1, 0.2), new Color(50, 50, 50));
    }

    /**
     * Draw Pyramid with one negative coordinate
     *
     * @param isometricView {@link IsometricView}
     */
    public void drawPyramidThree(IsometricView isometricView) {
        isometricView.add(new Pyramid(new Point(-1, 0, 0), 1, 1, 0.2), new Color(180, 180, 0));
    }

    /**
     * Draw Pyramid all negative coordinates
     *
     * @param isometricView {@link IsometricView}
     */
    public void drawPyramidFour(IsometricView isometricView) {
        isometricView.add(new Pyramid(new Point(-1, -1, -1), 1, 1, 0.2), new Color(33, 150, 243));
    }

    /**
     * Draw Pyramid translation point big
     *
     * @param isometricView {@link IsometricView}
     */
    public void drawPyramidFive(IsometricView isometricView) {
        isometricView.add(new Pyramid(new Point(0, 0, 0), 2, 2, 0.4), new Color(50, 50, 50));
    }

    /**
     * DrawStairs
     *
     * @param isometricView {@link IsometricView}
     */
    public void drawStairsOne(IsometricView isometricView) {
        isometricView.add(new Stairs(new Point(0, 0, 0), 10), new Color(33, 150, 243));
    }

    /**
     * Point with all negative coordinates
     *
     * @param isometricView {@link IsometricView}
     */
    public void drawStairsTwo(IsometricView isometricView) {
        isometricView.add(new Stairs(new Point(-1, -1, -1), 10), new Color(180, 180, 0));
    }

    /**
     * Point with one negative coordinates with more steps
     *
     * @param isometricView {@link IsometricView}
     */
    public void drawStairsThree(IsometricView isometricView) {
        isometricView.add(new Stairs(new Point(-1, 0, 0), 20), new Color(180, 0, 180));
    }

    /**
     * Multiple shapes with different colors
     *
     * @param isometricView {@link IsometricView}
     */
    public void multipleShapes(IsometricView isometricView) {
        // Code for Translate
        Prism prism = new Prism(new Point(0, 0, 0));
        isometricView.add(prism, new Color(33, 150, 243));
        isometricView.add(prism.translate(0, 0, 1.1), new Color(33, 150, 243));
        //Code for Scale
        Color blue = new Color(50, 60, 160);
        Color red = new Color(160, 60, 50);
        Prism cube = new Prism(Point.ORIGIN);
        isometricView.add(cube.scale(Point.ORIGIN, 3.0, 3.0, 0.5), red);
        isometricView.add(cube.scale(Point.ORIGIN, 3.0, 3.0, 0.5).translate(0, 0, 0.6), blue);
        // Code for Rotation
        Prism cube1 = new Prism(Point.ORIGIN, 3, 3, 1);
        isometricView.add(cube1, red);
        isometricView.add(cube1
            /* (1.5, 1.5) is the center of the prism */.rotateZ(new Point(1.5, 1.5, 0), Math.PI / 12)
            .translate(0, 0, 1.1), blue);
        // Code for Extrude
        isometricView.add(new Prism(Point.ORIGIN, 3, 3, 1), blue);
        isometricView.add(Shape.extrude(new Path(new Point[] {
            new Point(1, 1, 1), new Point(2, 1, 1), new Point(2, 3, 1)
        }), 0.3), red);
        // Adding Prism
        isometricView.add(new Prism(new Point(0, 0, 0)), new Color(33, 150, 243));
        // Adding Stairs
        isometricView.add(new Stairs(new Point(-1, 0, 0), 10), new Color(33, 150, 243));
        // Adding Pyramid
        isometricView.add(new Pyramid(new Point(2, 3, 3)), new Color(180, 180, 0));
        // Adding Octahedron
        isometricView.add(new Octahedron(new Point(3, 2, 3.2)), new Color(0, 180, 180));
        // Adding Cylinder
        isometricView.add(new Cylinder(new Point(3, 2, 3.2), 20, 8), new Color(180, 0, 180));
        // Adding Knot
        isometricView.add(new Knot(new Point(0, 0, 0)), new Color(33, 150, 243));
        // Adding negative co-ordinates
        isometricView.add(new Prism(new Point(-1, 0, -1)), new Color(33, 150, 243));
    }

    /**
     * Complex Shape with two different color
     *
     * @param isometricView {@link IsometricView}
     */
    public void complexShapeOne(IsometricView isometricView) {
        isometricView.add(new Prism(new Point(0, 0, 0), 4, 4, 2), new Color(180, 0, 180));
        isometricView.add(new Prism(new Point(-1, 1, 0), 1, 2, 1), new Color(33, 150, 243));
        isometricView.add(new Prism(new Point(1, -1, 0), 2, 1, 1), new Color(33, 150, 243));
    }

    /**
     * Complex Shape witch include different shapes like Prism,Pyramid,Stairs and Octahedron
     *
     * @param angle {@link double}
     * @param isometricView {@link IsometricView}
     */
    public void complexShapeTwo(double angle, IsometricView isometricView) {
        isometricView.clear();
        isometricView.add(new Prism(new Point(1, -1, 0), 4, 5, 2), new Color(33, 150, 243));
        isometricView.add(new Prism(new Point(0, 0, 0), 1, 4, 1), new Color(33, 150, 243));
        isometricView.add(new Prism(new Point(-1, 1, 0), 1, 3, 1), new Color(33, 150, 243));
        isometricView.add(new Stairs(new Point(-1, 0, 0), 10), new Color(33, 150, 243));
        isometricView.add(new Stairs(new Point(0, 3, 1), 10).rotateZ(new Point(0.5, 3.5, 1), -Math.PI / 2),
            new Color(33, 150, 243));
        isometricView.add(new Prism(new Point(3, 0, 2), 2, 4, 1), new Color(33, 150, 243));
        isometricView.add(new Prism(new Point(2, 1, 2), 1, 3, 1), new Color(33, 150, 243));
        isometricView.add(new Stairs(new Point(2, 0, 2), 10).rotateZ(new Point(2.5, 0.5, 0), -Math.PI / 2),
            new Color(33, 150, 243));
        isometricView.add(new Pyramid(new Point(2, 3, 3)).scale(new Point(2, 4, 3), 0.5), new Color(180, 180, 0));
        isometricView.add(new Pyramid(new Point(4, 3, 3)).scale(new Point(5, 4, 3), 0.5), new Color(180, 0, 180));
        isometricView.add(new Pyramid(new Point(4, 1, 3)).scale(new Point(5, 1, 3), 0.5), new Color(0, 180, 180));
        isometricView.add(new Pyramid(new Point(2, 1, 3)).scale(new Point(2, 1, 3), 0.5), new Color(40, 180, 40));
        isometricView.add(new Prism(new Point(3, 2, 3), 1, 1, 0.2), new Color(50, 50, 50));
        isometricView.add(new Octahedron(new Point(3, 2, 3.2)).rotateZ(new Point(4.5, 2.5, 1), angle),
            new Color(0, 180, 180));
    }

    /**
     * callback
     */
    @Override
    public void onActive() {
        super.onActive();
        HiLogs.e(TAG, "onActive() : ");
    }

    /**
     * callback
     *
     * @param intent
     */
    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
        HiLogs.e(TAG, "onForeground() : " + intent);
    }

}